<template>
  <div class="w-full h-full p-2 bg-FileList">
    <!-- 头部 -->
    <div class="flex flex-row justify-between items-center">
      <div>
        <slot name="title"></slot>
      </div>
      <el-select v-model="sortType" placeholder="Select" size="small" style="width: 150px">
        <el-option v-for="item in SelectFileListOption" :key="item.id" :label="item.label" :value="item.value" />
      </el-select>
    </div>
    <!-- 内容 -->
    <div class="h-[calc(100vh-120px)] overflow-y-scroll">
      <!-- list -->
      <template v-if="FilterFileList.length != 0">
        <ContextMenu
          v-for="(item, index) in FilterFileList"
          :key="index"
          :class="selectCurrentItem === index ? 'ListActive' : ''"
          :content="item"
          :menu-list="FileListMenu"
          class="grid grid-cols-[62px,1fr] items-center p-2 gap-2 rounded cursor-pointer"
          style="border-bottom: 1px solid var(--border)"
          @select="(event, MenuItem) => MenuItem.click(event, item)"
          @contextmenu.prevent="selectCurrentItem = index"
        >
          <div class="relative">
            <n-image :height="62" :src="GetFileTypeIcon(item.fileName || '')" :width="62" preview-disabled />
            <div
              v-if="!item.downloaded"
              class="w-full h-full absolute top-0 left-0 bg-[rgba(0,0,0,.7)] flex flex-col justify-center items-center"
              @click.stop="DownloadFile(item)"
            >
              <!-- 是否在下载中 -->
              <DownloadOutline v-if="item.progress === 0" class="w-[20px] h-[20px] text-white" />
              <div v-else>
                <el-progress :percentage="item.progress" :stroke-width="2" :width="40" type="circle">
                  <div class="w-full flex flex-row items-center pl-[8px]" @click.stop="CancelDownload(item)">
                    <PauseCircleSharp class="w-[25px] h-[25px] text-white" />
                  </div>
                </el-progress>
              </div>
            </div>
          </div>
          <div>
            <p class="flex justify-between items-center">
              <span class="text-[14px]">{{ item.fileName }}</span>
              <span class="text-[10px] text-placeholder">{{ FormatTime(item.updatedAt) }}</span>
            </p>
            <p class="text-[10px] mt-2">
              {{ FormatFileSize(item.fileSize) }}
            </p>
          </div>
        </ContextMenu>
      </template>
      <!-- empty -->
      <template v-else>
        <n-empty
          class="w-full h-full flex flex-col justify-center items-center"
          description="暂时没有文件"
          size="large"
        >
          <template #icon>
            <n-icon>
              <AirplaneOutline />
            </n-icon>
          </template>
        </n-empty>
      </template>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, ref } from "vue";
import { IDownLoadDone, IDownloadProgress, IFileListItem, IFileListProps } from "@/types/file";
import { useSystem } from "@/store/modules/system";
import { useUser } from "@/store/modules/user";
import { useFileListMenu } from "@/hooks/useMenu.ts";
import { FormatTime } from "@/utils/time.ts";
import { FormatFileSize, GetFileTypeIcon } from "@/utils/file.ts";
import { ElMessage } from "element-plus";
import { NEmpty, NIcon, NImage } from "naive-ui";
import ContextMenu from "@/components/ContextMenu/index.vue";
import { SelectFileListOption } from "@/utils/common.ts";
import { AirplaneOutline, DownloadOutline, PauseCircleSharp } from "@vicons/ionicons5";
import { useChat } from "@/store/modules/chat.ts";

const user = useUser();
const system = useSystem();
const chat = useChat();
const { FileListMenu } = useFileListMenu();

let selectCurrentItem = ref();
let sortType = ref(1);
const fileListMap = reactive(new Map<string, IFileListItem>());
const fileList = defineModel<IFileListItem[]>("fileList", {
  default: () => [],
});
const props = defineProps<{
  data: IFileListProps;
}>();
const FilterFileList = computed<IFileListItem[]>(() => {
  return fileList.value.sort((a, b) => {
    switch (sortType.value) {
      case 1: // 按新时间排序 (最新在前)
        return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
      case 2: // 按旧时间排序 (最旧在前)
        return new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime();
      case 3: // 按文件从大到小
        return b.fileSize - a.fileSize;
      case 4: // 按文件从小到大
        return a.fileSize - b.fileSize;
      default:
        return 0; // 保持原顺序
    }
  });
});

// 下载文件
async function DownloadFile(item: IFileListItem) {
  const savePath = system.DefaultDownloadPath as string;
  if (!savePath) return;
  window.electronApi.downloadFile({
    savePath,
    userId: user.userId!,
    fileUrl: item.fileUrl,
    taskId: item.uuid,
  });
}

// 更新消息列表
function UpdateChatMessageList(taskId: string, localPath: string) {
  if (!chat.ChatObject || !props.data.type) return;
  if (props.data.type != chat.ChatObject.chatType || props.data.id != chat.ChatObject.id) return;
  const index = chat.MessageList.findIndex((m) => m.uuid === taskId);
  if (index === -1) return;
  chat.MessageList[index].localPath = localPath;
}

// 下载进度回调
window.electronApi.downloadProgress((data: IDownloadProgress) => {
  const { taskId, progress } = data;
  let taskItem = fileListMap.get(taskId);
  if (!taskItem) {
    const index = fileList.value.findIndex((item) => item.uuid === taskId);
    if (index !== -1) {
      fileListMap.set(taskId, fileList.value[index]);
      taskItem = fileList.value[index];
    }
  }
  if (taskItem) taskItem.progress = progress;
});

// 下载完成回调
window.electronApi.downloadDone((data: IDownLoadDone) => {
  const { state, taskId, fileSavePath } = data;
  if (state != "completed") {
    ElMessage.error("下载出现错误了");
    return;
  }
  let taskItem = fileListMap.get(taskId);
  if (taskItem) {
    taskItem.downloaded = true;
    taskItem.localPath = fileSavePath;
  }
  fileListMap.delete(taskId);
  // 更新聊天记录
  UpdateChatMessageList(taskId, fileSavePath);
});

// 取消下载
function CancelDownload(item: IFileListItem) {
  item.downloaded = false;
  item.progress = 0;
  window.electronApi.cancelDownload(item.uuid);
}
</script>

<style lang="scss" scoped>
.ListActive {
  background-color: var(--session-hover);
}
</style>
